package dal;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;

import dal.datastore.IDataStoreConfig;
import dto.AuthenticationDTO;

public class AuthenticationDAO implements IDataStoreConfig {

	/**
	 * Get all account in auth_file
	 * 
	 * @return
	 * @throws JsonIOException
	 * @throws JsonSyntaxException
	 * @throws FileNotFoundException
	 */
	public ArrayList<AuthenticationDTO> getAllAccount() throws JsonIOException,
			JsonSyntaxException, FileNotFoundException {
		ArrayList<AuthenticationDTO> collection = new ArrayList<>();
		Gson gson = new Gson();
		JsonParser parser = new JsonParser();
		JsonArray array;

		// 1. Get all accounts
		array = parser.parse(new FileReader(new File(AUTH_FILE)))
				.getAsJsonArray();
		for (JsonElement element : array) {
			AuthenticationDTO account = gson.fromJson(element,
					AuthenticationDTO.class);
			collection.add(account);
		}
		return collection;
	}

	/**
	 * Get an account with user name
	 * 
	 * @param username
	 * @return AuthenticationDTO if account exists.
	 * @throws Exception
	 */
	public AuthenticationDTO getAccount(String username) throws Exception {
		// 1. Get all databases
		Collection<AuthenticationDTO> collection;
		try {
			collection = getAllAccount();
			for (AuthenticationDTO authenticationDTO : collection) {
				if (authenticationDTO.get_username().equals(username)) {
					return authenticationDTO;
				}
			}
		} catch (Exception e) {
			throw e;
		}
		return null;
	}

	/**
	 * Create an account.
	 * 
	 * @param info
	 * @return true if create successful
	 * @throws IOException
	 */
	public boolean createAccount(AuthenticationDTO info) throws IOException {
		Gson gson = new Gson();

		// 1. Get all databases
		Collection<AuthenticationDTO> collection;
		try {
			collection = getAllAccount();
		} catch (Exception e) {
			collection = new ArrayList<AuthenticationDTO>();
		}

		// 2. add new account
		collection.add(info);

		// 3. Write to json file
		String json = gson.toJson(collection);
		FileWriter fw = new FileWriter(new File(AUTH_FILE));
		BufferedWriter bf = new BufferedWriter(fw);
		bf.write(json);
		bf.close();
		fw.close();

		return true;
	}

	/**
	 * Remove account from auth_file
	 * 
	 * @param info
	 * @return true if succeed.
	 * @throws IOException
	 */
	public boolean removeAccount(AuthenticationDTO info) throws IOException {
		Gson gson = new Gson();

		// 1. Get all databases
		Collection<AuthenticationDTO> collection;
		try {
			collection = getAllAccount();
		} catch (Exception e) {
			collection = new ArrayList<AuthenticationDTO>();
		}

		// 2. remove new account
		collection.remove(info);

		// 3. Write to json file
		String json = gson.toJson(collection);
		FileWriter fw = new FileWriter(new File(AUTH_FILE));
		BufferedWriter bf = new BufferedWriter(fw);
		bf.write(json);
		bf.close();
		fw.close();

		return true;
	}
}
